bitkeeper revision 1.1159.68.3 (41385101Grb5mmJcQ0YiLdCY2dOnCg)
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Fri, 3 Sep 2004 11:09:53 +0000 (11:09 +0000)
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Fri, 3 Sep 2004 11:09:53 +0000 (11:09 +0000)
Notify device controllers when devices are added or removed so
that they can probe for the devices.

linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c
linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c
tools/python/xen/xend/XendClient.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/server/blkif.py
tools/python/xen/xend/server/messages.py
tools/python/xen/xend/server/netif.py
tools/python/xen/xm/main.py
xen/include/hypervisor-ifs/io/domain_controller.h

index 930e469103db04e02f2bbd9131e1770a0f9b37e7..259275ebd13d69648e8ca62e5291efec05a0fa82 100644 (file)
@@ -1148,6 +1148,12 @@ static void blkif_status_change(blkif_fe_interface_status_changed_t *status)
 
         break;
 
+    case BLKIF_INTERFACE_STATUS_CHANGED:
+        /* The domain controller is notifying us that a device has been
+        * added or removed.
+        */
+        break;
+
     default:
         printk(KERN_WARNING "Status change to unknown value %d\n", 
                status->status);
index 85e29d4d25983dfcdd860ddff63b4489ee659216..44aa8e9ddefde742b9ccce091b699bf68cf87f3d 100644 (file)
@@ -771,6 +771,12 @@ static void netif_status_change(netif_fe_interface_status_changed_t *status)
         vif_wake(dev);
         break;
 
+    case NETIF_INTERFACE_STATUS_CHANGED:
+        /* The domain controller is notifying us that a device has been
+        * added or removed.
+        */
+        break;
+
     default:
         printk(KERN_WARNING "Status change to unknown value %d\n", 
                status->status);
index 5041e06cb744a6dfc3bb015ceb6fbfe2b5415388..01d6d3df3cff7e1fde0b2bd0b55f9330f27bb9bb 100644 (file)
@@ -548,7 +548,7 @@ class Xend:
         return self.xendPost(self.domainurl(id),
                              {'op'      : 'device_destroy',
                               'type'    : type,
-                              'index'   : idx })
+                              'idx'     : idx })
 
     def xend_consoles(self):
         return self.xendGet(self.consoleurl())
index b86167143baf0ed79b38b478a6b03b74a9c093d6..f582a511455ff3bd6d83719e3f357a26400f54f6 100644 (file)
@@ -576,6 +576,16 @@ class XendDomainInfo:
         dl.append(dev)
         self.devices[type] = dl
 
+    def remove_device(self, type, dev):
+        """Remove a device from a virtual machine.
+
+        @param type: device type
+        @param dev:  device
+        """
+        dl = self.devices.get(type, [])
+        if dev in dl:
+            dl.remove(dev)
+
     def get_devices(self, type):
         """Get a list of the devices of a given type.
 
@@ -812,7 +822,7 @@ class XendDomainInfo:
         devs = self.get_devices(dev_name)
         dev_index = len(devs)
         self.config.append(['device', dev_config])
-        d = dev_handler(self, dev_config, dev_index)
+        d = dev_handler(self, dev_config, dev_index, change=1)
         return d
 
     def device_destroy(self, type, idx):
@@ -829,7 +839,8 @@ class XendDomainInfo:
         dev_config = self.config_device(type, index)
         if dev_config:
             self.config.remove(['device', dev_config])
-        dev.destroy()
+        dev.destroy(change=1)
+        self.remove_device(type, dev)
 
     def configure_memory(self):
         """Configure vm memory limit.
@@ -1053,7 +1064,7 @@ def vm_image_netbsd(vm, image):
     return vm
 
 
-def vm_dev_vif(vm, val, index):
+def vm_dev_vif(vm, val, index, change=0):
     """Create a virtual network interface (vif).
 
     @param vm:        virtual machine
@@ -1069,11 +1080,13 @@ def vm_dev_vif(vm, val, index):
     def cbok(dev):
         dev.vifctl('up', vmname=vm.name)
         vm.add_device('vif', dev)
+        if change:
+            dev.interfaceChanged()
         return dev
     defer.addCallback(cbok)
     return defer
 
-def vm_dev_vbd(vm, val, index):
+def vm_dev_vbd(vm, val, index, change=0):
     """Create a virtual block device (vbd).
 
     @param vm:        virtual machine
@@ -1094,6 +1107,8 @@ def vm_dev_vbd(vm, val, index):
         vbd.dev = dev
         vbd.uname = uname
         vm.add_device('vbd', vbd)
+        if change:
+            vbd.interfaceChanged()
         return vbd
     defer.addCallback(fn)
     return defer
@@ -1110,7 +1125,7 @@ def parse_pci(val):
         v = val
     return v
 
-def vm_dev_pci(vm, val, index):
+def vm_dev_pci(vm, val, index, change=0):
     """Add a pci device.
 
     @param vm: virtual machine
index c3c3eb2de3b90ddc129d62e36987b6052cb6e001..60708e24a97311a2732f452d643bdc31d058d4fd 100755 (executable)
@@ -3,7 +3,6 @@
 """
 
 from twisted.internet import defer
-#defer.Deferred.debug = 1
 
 from xen.xend import sxp
 from xen.xend.XendLogging import log
@@ -88,14 +87,12 @@ class BlkifBackendInterface(controller.BackendInterface):
         self.send_be_disconnect(response=d)
         
     def send_be_disconnect(self, response=None):
-        log.debug('>BlkifBackendController>send_be_disconnect> %s', str(self))
         msg = packMsg('blkif_be_disconnect_t',
                       { 'domid'        : self.controller.dom,
                         'blkif_handle' : self.handle })
         self.writeRequest(msg, response=response)
 
     def send_be_destroy(self, response=None):
-        log.debug('>BlkifBackendController>send_be_destroy> %s', str(self))
         msg = packMsg('blkif_be_destroy_t',
                       { 'domid'        : self.controller.dom,
                         'blkif_handle' : self.handle })
@@ -127,9 +124,28 @@ class BlkifBackendInterface(controller.BackendInterface):
         msg = packMsg('blkif_fe_interface_status_changed_t',
                       { 'handle' : self.handle,
                         'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
-                        'domid'  : 0, ## FIXME: should be domid of backend
+                        'domid'  : self.dom,
                         'evtchn' : self.evtchn['port2'] })
         self.controller.writeRequest(msg, response=response)
+
+    def interfaceDisconnected(self):
+        msg = packMsg('blkif_fe_interface_status_changed_t',
+                      { 'handle' : self.handle,
+                        'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
+                        'domid'  : self.dom,
+                        'evtchn' : 0 })
+        self.controller.writeRequest(msg)
+        
+    def interfaceChanged(self):
+        """Notify the front-end that devices have been added or removed.
+        The front-end should then probe for devices.
+        """
+        msg = packMsg('blkif_fe_interface_status_changed_t',
+                      { 'handle' : self.handle,
+                        'status' : BLKIF_INTERFACE_STATUS_CHANGED,
+                        'domid'  : self.dom,
+                        'evtchn' : 0 })
+        self.controller.writeRequest(msg)
         
 class BlkifControllerFactory(controller.SplitControllerFactory):
     """Factory for creating block device interface controllers.
@@ -230,9 +246,21 @@ class BlkDev(controller.SplitDev):
             val.append(['uname', self.uname])
         return val
 
-    def destroy(self):
+    def destroy(self, change=0):
+        """Destroy the device. If 'change' is true notify the front-end interface.
+
+        @param change: change flag
+        """
         log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
-        self.send_be_vbd_destroy()
+        d = self.send_be_vbd_destroy()
+        if change:
+            d.addCallback(lambda val: self.interfaceChanged())
+
+    def interfaceChanged(self):
+        """Tell the back-end to notify the front-end that a device has been
+        added or removed.
+        """
+        self.getBackendInterface().interfaceChanged()
 
     def attach(self):
         """Attach the device to its controller.
@@ -295,16 +323,16 @@ class BlkDev(controller.SplitDev):
                             % (self.vdev, status))
         return self
 
-    def send_be_vbd_destroy(self, response=None):
-        log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d',
-                  self.controller.dom, self.vdev)
+    def send_be_vbd_destroy(self):
+        d = defer.Deferred()
         backend = self.getBackendInterface()
         msg = packMsg('blkif_be_vbd_destroy_t',
                       { 'domid'                : self.controller.dom,
                         'blkif_handle'         : backend.handle,
                         'vdevice'              : self.vdev })
         self.controller.delDevice(self.vdev)
-        backend.writeRequest(msg, response=response)
+        backend.writeRequest(msg, response=d)
+        return d
         
         
 class BlkifController(controller.SplitController):
@@ -399,13 +427,8 @@ class BlkifController(controller.SplitController):
 
     def recv_fe_driver_status_changed(self, msg, req):
         val = unpackMsg('blkif_fe_driver_status_changed_t', msg)
-        # For each backend?
-        msg = packMsg('blkif_fe_interface_status_changed_t',
-                      { 'handle' : 0,
-                        'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
-                        'domid'  : 0, ## FIXME: should be domid of backend
-                        'evtchn' : 0 })
-        self.writeRequest(msg)
+        for backend in self.getBackendInterfaces():
+            backend.interfaceDisconnected()
 
     def recv_fe_interface_connect(self, msg, req):
         val = unpackMsg('blkif_fe_interface_connect_t', msg)
index 8d68d95887c3c611069d5aed9649177132c56920..fb94214a6461e9fdef1e2db062b2f9e338845198 100644 (file)
@@ -50,6 +50,7 @@ BLKIF_DRIVER_STATUS_UP    = 1
 BLKIF_INTERFACE_STATUS_DESTROYED    = 0 #/* Interface doesn't exist.    */
 BLKIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
 BLKIF_INTERFACE_STATUS_CONNECTED    = 2 #/* Exists and is connected.    */
+BLKIF_INTERFACE_STATUS_CHANGED      = 3 #/* A device has been added or removed. */
 
 BLKIF_BE_STATUS_OKAY                = 0
 BLKIF_BE_STATUS_ERROR               = 1
@@ -117,6 +118,7 @@ CMSG_NETIF_BE_DRIVER_STATUS_CHANGED    = 32
 NETIF_INTERFACE_STATUS_DESTROYED    = 0 #/* Interface doesn't exist.    */
 NETIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
 NETIF_INTERFACE_STATUS_CONNECTED    = 2 #/* Exists and is connected.    */
+NETIF_INTERFACE_STATUS_CHANGED      = 3 #/* A device has been added or removed. */
 
 NETIF_DRIVER_STATUS_DOWN   = 0
 NETIF_DRIVER_STATUS_UP     = 1
index 3b4dc25339ef2cc68df3ddb02244c3875c1f14a7..3c07333a8496da0ac8d56dc62d2b99167c36240e 100755 (executable)
@@ -5,7 +5,6 @@
 import random
 
 from twisted.internet import defer
-#defer.Deferred.debug = 1
 
 from xen.xend import sxp
 from xen.xend import Vifctl
@@ -208,13 +207,17 @@ class NetDev(controller.SplitDev):
         val = unpackMsg('netif_be_create_t', msg)
         return self
 
-    def destroy(self):
+    def destroy(self, change=0):
         """Destroy the device's resources and disconnect from the back-end
-        device controller.
+        device controller. If 'change' is true notify the front-end interface.
+
+        @param change: change flag
         """
         def cb_destroy(val):
             self.send_be_destroy()
             self.getBackendInterface().close()
+            if change:
+                self.interfaceChanged()
         log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
         self.vifctl('down')
         d = self.send_be_disconnect()
@@ -256,7 +259,7 @@ class NetDev(controller.SplitDev):
                       { 'handle' : self.vif,
                         'status' : NETIF_INTERFACE_STATUS_CONNECTED,
                         'evtchn' : self.evtchn['port2'],
-                        'domid'  : 0, ## FIXME: should be domid of backend
+                        'domid'  : self.backendDomain,
                         'mac'    : self.mac })
         self.controller.writeRequest(msg)
 
@@ -265,7 +268,19 @@ class NetDev(controller.SplitDev):
                       { 'handle' : self.vif,
                         'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
                         'evtchn' : 0,
-                        'domid'  : 0, ## FIXME: should be domid of backend
+                        'domid'  : self.backendDomain,
+                        'mac'    : self.mac })
+        self.controller.writeRequest(msg)
+
+    def interfaceChanged(self):
+        """Notify the font-end that a device has been added or removed.
+        The front-end should then probe the devices.
+        """
+        msg = packMsg('netif_fe_interface_status_changed_t',
+                      { 'handle' : self.vif,
+                        'status' : NETIF_INTERFACE_STATUS_CHANGED,
+                        'evtchn' : 0,
+                        'domid'  : self.backendDomain,
                         'mac'    : self.mac })
         self.controller.writeRequest(msg)
         
index 2d77bd5ca6f385ac37bbbab07054ad22f7d3d968..d8c70e75fec6e7bd59e4c9374e60c2fec1608f60 100644 (file)
@@ -737,22 +737,26 @@ class ProgVbdCreate(Prog):
     info = """Create a new virtual block device for a domain"""
 
     def help(self, args):
-        print args[0], "DOM UNAME DEV MODE"
+        print args[0], "DOM UNAME DEV MODE [BACKEND]"
         print """
 Create a virtual block device for a domain.
 
-  UNAME - device to export, e.g. phys:hda2
-  DEV   - device name in the domain, e.g. xda1
-  MODE  - access mode: r for read, w for read-write
+  UNAME   - device to export, e.g. phy:hda2
+  DEV     - device name in the domain, e.g. xda1
+  MODE    - access mode: r for read, w for read-write
+  BACKEND - backend driver domain
 """
 
     def main(self, args):
-        if len(args) != 5: self.err("%s: Invalid argument(s)" % args[0])
+        n = len(args)
+        if n < 5 or n > 6: self.err("%s: Invalid argument(s)" % args[0])
         dom = args[1]
         vbd = ['vbd',
                ['uname', args[2]],
                ['dev',   args[3]],
                ['mode',  args[4]]]
+        if n == 6:
+            vbd.append(['backend', args[5]])
         server.xend_domain_device_create(dom, vbd)
 
 xm.prog(ProgVbdCreate)
@@ -766,13 +770,15 @@ class ProgVbdDestroy(Prog):
         print args[0], "DOM DEV"
         print """
 Destroy vbd DEV attached to domain DOM. Detaches the device
-from the domain, but does not destroy the device contents."""
+from the domain, but does not destroy the device contents.
+The device indentifier DEV is the idx field in the device
+information. This is visible in 'xm vbd-list'."""
 
     def main(self, args):
-        if len(args!=3): self.err("%s: Invalid argument(s)" % args[0])
+        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
         dom = args[1]
         dev = args[2]
-        sever.xend_domain_device_destroy(dom, "vbd", dev)
+        server.xend_domain_device_destroy(dom, "vbd", dev)
 
 xm.prog(ProgVbdDestroy)
 
index 45090aca0fd5d28babc382de48302e4126eae450..5de3c2d673c2d1e8e3b0ad0c3b5f4f01c8649a8b 100644 (file)
@@ -93,6 +93,7 @@ typedef struct {
 #define BLKIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
 #define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
 #define BLKIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
+#define BLKIF_INTERFACE_STATUS_CHANGED      3 /* A device has been added or removed. */
 typedef struct {
     u32 handle; /*  0 */
     u32 status; /*  4 */
@@ -357,6 +358,7 @@ typedef struct {
 #define NETIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
 #define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
 #define NETIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
+#define NETIF_INTERFACE_STATUS_CHANGED      3 /* A device has been added or removed. */
 typedef struct {
     u32        handle; /*  0 */
     u32        status; /*  4 */